﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;

namespace EIA.WCFService.AuthenticationService
{
    /// <summary>
    /// [O] PerCall
    /// [ ] PerSession：客户端增加，将增加调用上下文实例数量，占用数据库连接会话数量小于客户端数量
    /// [X] Singleton: 需要自己控制锁，保持数据一致性。（所有实例共用一个数据库连接）
    /// </summary>
    [ServiceBehavior(
        InstanceContextMode = InstanceContextMode.PerCall,
        ConcurrencyMode = ConcurrencyMode.Reentrant,
        UseSynchronizationContext = false)]
    public class Service : IAuthenticationService
    {
        public Service()
        {
            string connStr = DotNETX.Utility.Config.AppConfigUtils.TryGetSetting<string>(this.GetType(), "EIA.Authentication.ConnectionString");
            System.Data.IDbConnection con = DotNETX.Authentication.Db.MySql.ConnectionUtils.CreateMySqlConnection(connStr);
            
            Authenticater = new DotNETX.Authentication.Authenticater(
                    DotNETX.Authentication.Db.MySqlUserManager.Create(con, "t_user", "login_id", "login_pwd", "stf_id", "login_avalible=1"),
                    DotNETX.Authentication.Db.MySqlTokenManager.Create(con, "t_login_session", "ses_token", "stf_id", "login_time", "last_vist_time", "is_active"));
        }

        public DotNETX.Authentication.Authenticater Authenticater
        {
            get;
            set;
        }

        #region IAuthenticationService

        public string Login(string loginid, string pwd)
        {
            try
            {
                string token = Authenticater.Login(loginid, pwd);
                if (token == null) return null;
                string uniqueid = Authenticater.GetUId(token);
                return token;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public int Logout(string token)
        {
            try
            {
                int r = Authenticater.Logout(token);
                return r;
            }
            catch (Exception ex)
            {
                return int.MaxValue;
            }
        }

        public string GetUniqueId(string token)
        {
            try
            {
                string id = Authenticater.GetUId(token);
                return id;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public string GetLoginTime(string token)
        {
            try
            {
                DotNETX.Authentication.UserSession session = Authenticater.TokenManager.GetSession(token);
                if(session != null)
                {
                    return session.LoginTime.ToString("yyyy-MM-dd HH:mm:ss");
                }
                return null;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public bool ChangePassword(string loginid, string oldpwd, string newpwd)
        {
            try
            {
                DotNETX.Authentication.UserIdentifier ui = Authenticater.UserManager.Find(loginid);
                if (ui != null && ui.Password == oldpwd)
                {
                    bool r = Authenticater.UserManager.SetPassword(loginid, newpwd);
                    return r;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        #endregion


        public System.IO.Stream GetClientAccessPolicy()
        {
            WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";
            System.IO.MemoryStream ms = new System.IO.MemoryStream();

            System.IO.StreamWriter sw = new System.IO.StreamWriter(ms,Encoding.UTF8);;
            sw.Write("<?xml version=\"1.0\" encoding=\"utf-8\"?><access-policy><cross-domain-access><policy><allow-from http-request-headers=\"*\"><domain uri=\"*\"/></allow-from><grant-to><resource path=\"/\" include-subpaths=\"true\"/></grant-to></policy></cross-domain-access></access-policy>");
            sw.Flush();
            ms.Position = 0;
            return ms;
        }

    }
}
